using System;
using EnvDTE;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using EnvDTE80;

namespace TeamReview.Replay
{
	internal class CodeElementLink : ReplayLink
	{
		private string _workItemField;
		private string _displayName;

		protected string DisplayName
		{
			get { return _displayName; }
		}

        public CodeElementLink(EnvDTE80.DTE2 applicationObject, string workItemField, string displayField) : base(applicationObject)
		{
            if (string.IsNullOrEmpty(workItemField))
		    {
		        throw new ArgumentNullException(workItemField);
		    }

            if (string.IsNullOrEmpty(workItemField))
            {
                throw new ArgumentNullException(displayField);
            }

			_workItemField = workItemField;
			_displayName = displayField;
		}


        public override ReplayReceipt TryShowReplay(WorkItem workItem, DTE2 applicationObject)
		{
			ReplayReceipt receipt = new ReplayReceipt();

			EnvDTE.Project project = GetProject(workItem);
			object snippetObject = workItem.Fields[Constants.CODE_SNIPPET_FIELD].Value;
            object codeElementObject = workItem.Fields[_workItemField].Value;

			if (project == null || snippetObject == null || codeElementObject == null)
				return receipt;

			string snippet = snippetObject.ToString();
			string codeElement = codeElementObject.ToString();

			if (String.IsNullOrEmpty(codeElement))
				return receipt;

			CodeElement foundElement = FindElement(project.ProjectItems, codeElement);
			
			if (foundElement == null)
				return receipt;


			//TODO: what if there are multiple file names?
			//TODO: can there be no file names?
			EnvDTE.Document document = applicationObject.Documents.Open(foundElement.ProjectItem.get_FileNames(0), "Auto", false);
			if (document == null)
				return receipt;

			EnvDTE.TextDocument td = (EnvDTE.TextDocument)document.Object("");
			if (td == null)
				return receipt;

			receipt.Selection = td.Selection;
			receipt.ItemWasFound = true;
			receipt.Outcome = String.Format("Review Item found by {0} name. Exact code NOT found within the {0} body.", DisplayName);
			receipt.Selection.GotoLine(foundElement.StartPoint.Line, false);
			EnvDTE.EditPoint startPoint = td.CreateEditPoint(receipt.Selection.ActivePoint);
			receipt.Selection.GotoLine(foundElement.EndPoint.Line, true);
			EnvDTE.EditPoint endPoint = td.CreateEditPoint(receipt.Selection.ActivePoint);
			receipt.Selection.MoveToPoint(startPoint, false);
			receipt.Selection.MoveToPoint(endPoint, true);

			return receipt;
		}
	}
}
